import re

import moderngl
from PIL import Image


def load_shader(path: str) -> dict[str, str]:
    shaders = {}
    with open(path) as file:
        shader_str = file.read()
    if 'if VERTEX_SHADER' in shader_str:
        vertex_shader = re.sub(r'(#version +\d+)', r'\1\n#define VERTEX_SHADER 1\n', shader_str, count=1)
        shaders['vertex_shader'] = vertex_shader
    if 'if FRAGMENT_SHADER' in shader_str:
        fragment_shader = re.sub(r'(#version +\d+)', r'\1\n#define FRAGMENT_SHADER 1\n', shader_str, count=1)
        shaders['fragment_shader'] = fragment_shader
    if 'if GEOMETRY_SHADER' in shader_str:
        geometry_shader = re.sub(r'(#version +\d+)', r'\1\n#define GEOMETRY_SHADER 1\n', shader_str, count=1)
        shaders['geometry_shader'] = geometry_shader
    return shaders


_location_id = 0
_textures: dict[str, tuple[moderngl.Texture, int]] = {}


def load_texture(ctx: moderngl.Context, image_path: str) -> tuple[moderngl.Texture, int]:
    global _location_id
    global _textures
    if image_path not in _textures:
        texture_id = _location_id
        image = Image.open(image_path)
        data = image.tobytes()
        components = len(data) // (image.size[0] * image.size[1])
        texture = ctx.texture(image.size, components, data)
        texture.build_mipmaps()
        texture.use(location=texture_id)
        _location_id += 1
        _textures[image_path] = (texture, texture_id)
    return _textures[image_path]
